home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / setup.py < prev    next >
Text File  |  2009-10-09  |  35KB  |  897 lines

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19. #
  20. # Author: Don Welch
  21. #
  22.  
  23.  
  24. __version__ = '9.0'
  25. __title__ = 'Printer/Fax Setup Utility'
  26. __mod__ = 'hp-setup'
  27. __doc__ = "Installs HPLIP printers and faxes in the CUPS spooler. Tries to automatically determine the correct PPD file to use. Allows the printing of a testpage. Performs basic fax parameter setup."
  28.  
  29. # Std Lib
  30. import sys
  31. import getopt
  32. import time
  33. import os.path
  34. import re
  35. import os
  36. import gzip
  37.  
  38. try:
  39.     import readline
  40. except ImportError:
  41.     pass
  42.  
  43. # Local
  44. from base.g import *
  45. from base import device, utils, tui, models, module
  46. from prnt import cups
  47.  
  48. pm = None
  49.  
  50. def plugin_download_callback(c, s, t):
  51.     pm.update(int(100*c*s/t),
  52.              utils.format_bytes(c*s))
  53.  
  54.  
  55. nickname_pat = re.compile(r'''\*NickName:\s*\"(.*)"''', re.MULTILINE)
  56.  
  57. USAGE = [ (__doc__, "", "name", True),
  58.           ("Usage: %s [MODE] [OPTIONS] [SERIAL NO.|USB bus:device|IP|DEVNODE]" % __mod__, "", "summary", True),
  59.           utils.USAGE_MODE,
  60.           utils.USAGE_GUI_MODE,
  61.           utils.USAGE_INTERACTIVE_MODE,
  62.           utils.USAGE_SPACE,
  63.           utils.USAGE_OPTIONS,
  64.           ("Automatic mode:", "-a or --auto (-i mode only)", "option", False),
  65.           ("To specify the port on a multi-port JetDirect:", "--port=<port> (Valid values are 1\*, 2, and 3. \*default)", "option", False),
  66.           ("No testpage in automatic mode:", "-x (-i mode only)", "option", False),
  67.           ("To specify a CUPS printer queue name:", "-p<printer> or --printer=<printer> (-i mode only)", "option", False),
  68.           ("To specify a CUPS fax queue name:", "-f<fax> or --fax=<fax> (-i mode only)", "option", False),
  69.           ("Type of queue(s) to install:", "-t<typelist> or --type=<typelist>. <typelist>: print*, fax\* (\*default) (-i mode only)", "option", False),
  70.           ("To specify the device URI to install:", "-d<device> or --device=<device> (--qt4 mode only)", "option", False),
  71.           ("Remove printers or faxes instead of setting-up:", "-r or --rm or --remove (-u only)", "option", False),
  72.           utils.USAGE_LANGUAGE,
  73.           utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
  74.           utils.USAGE_HELP,
  75.           ("[SERIAL NO.|USB ID|IP|DEVNODE]", "", "heading", False),
  76.           ("USB bus:device (usb only):", """"xxx:yyy" where 'xxx' is the USB bus and 'yyy' is the USB device. (Note: The ':' and all leading zeros must be present.)""", 'option', False),
  77.           ("", "Use the 'lsusb' command to obtain this information.", "option", False),
  78.           ("IPs (network only):", 'IPv4 address "a.b.c.d" or "hostname"', "option", False),
  79.           ("DEVNODE (parallel only):", '"/dev/parportX", X=0,1,2,...', "option", False),
  80.           ("SERIAL NO. (usb and parallel only):", '"serial no."', "option", True),
  81.           utils.USAGE_EXAMPLES,
  82.           ("Setup using GUI mode:", "$ hp-setup", "example", False),
  83.           ("Setup using GUI mode, specifying usb:", "$ hp-setup -b usb", "example", False),
  84.           ("Setup using GUI mode, specifying an IP:", "$ hp-setup 192.168.0.101", "example", False),
  85.           ("One USB printer attached, automatic:", "$ hp-setup -i -a", "example", False),
  86.           ("USB, IDs specified:", "$ hp-setup -i 001:002", "example", False),
  87.           ("Network:", "$ hp-setup -i 66.35.250.209", "example", False),
  88.           ("Network, Jetdirect port 2:", "$ hp-setup -i --port=2 66.35.250.209", "example", False),
  89.           ("Parallel:", "$ hp-setup -i /dev/parport0", "example", False),
  90.           ("USB or parallel, using serial number:", "$ hp-setup -i US12345678A", "example", False),
  91.           ("USB, automatic:", "$ hp-setup -i --auto 001:002", "example", False),
  92.           ("Parallel, automatic, no testpage:", "$ hp-setup -i -a -x /dev/parport0", "example", False),
  93.           ("Parallel, choose device:", "$ hp-setup -i -b par", "example", False),
  94.           utils.USAGE_SPACE,
  95.           utils.USAGE_NOTES,
  96.           ("1. If no serial number, USB ID, IP, or device node is specified, the USB and parallel busses will be probed for devices.", "", 'note', False),
  97.           ("2. Using 'lsusb' to obtain USB IDs: (example)", "", 'note', False),
  98.           ("   $ lsusb", "", 'note', False),
  99.           ("         Bus 003 Device 011: ID 03f0:c202 Hewlett-Packard", "", 'note', False),
  100.           ("   $ hp-setup --auto 003:011", "", 'note', False),
  101.           ("   (Note: You may have to run 'lsusb' from /sbin or another location. Use '$ locate lsusb' to determine this.)", "", 'note', True),
  102.           ("3. Parameters -a, -f, -p, or -t are not valid in GUI (-u) mode.", "", 'note', True),
  103.           utils.USAGE_SPACE,
  104.           utils.USAGE_SEEALSO,
  105.           ("hp-makeuri", "", "seealso", False),
  106.           ("hp-probe", "", "seealso", False),
  107.         ]
  108.  
  109.  
  110. def showPasswordUI(prompt):
  111.     import getpass
  112.     print ""
  113.     print log.bold(prompt)
  114.     username = raw_input("Username: ")
  115.     password = getpass.getpass("Password: ")
  116.  
  117.     return (username, password)
  118.  
  119.  
  120. def restart_cups():
  121.     if os.path.exists('/etc/init.d/cups'):
  122.         return '/etc/init.d/cups restart'
  123.  
  124.     elif os.path.exists('/etc/init.d/cupsys'):
  125.         return '/etc/init.d/cupsys restart'
  126.  
  127.     else:
  128.         return 'killall -HUP cupsd'
  129.  
  130.  
  131. mod = module.Module(__mod__, __title__, __version__, __doc__, USAGE,
  132.                     (INTERACTIVE_MODE, GUI_MODE),
  133.                     (UI_TOOLKIT_QT3, UI_TOOLKIT_QT4),
  134.                     run_as_root_ok=True)
  135.  
  136. opts, device_uri, printer_name, mode, ui_toolkit, loc = \
  137.     mod.parseStdOpts('axp:P:f:t:b:d:r',
  138.                      ['ttl=', 'filter=', 'search=', 'find=',
  139.                       'method=', 'time-out=', 'timeout=',
  140.                       'printer=', 'fax=', 'type=', 'port=',
  141.                        'auto', 'device=', 'rm', 'remove'],
  142.                       handle_device_printer=False)
  143.  
  144.  
  145. printer_name = None
  146. fax_name = None
  147. bus = None
  148. setup_print = True
  149. setup_fax = True
  150. makeuri = None
  151. auto = False
  152. testpage_in_auto_mode = True
  153. jd_port = 1
  154. remove = False
  155.  
  156. for o, a in opts:
  157.     if o == '-x':
  158.         testpage_in_auto_mode = False
  159.  
  160.     elif o in ('-P', '-p', '--printer'):
  161.         printer_name = a
  162.  
  163.     elif o in ('-f', '--fax'):
  164.         fax_name = a
  165.  
  166.     elif o in ('-d', '--device'):
  167.         device_uri = a
  168.  
  169.     elif o in ('-b', '--bus'):
  170.         bus = [x.lower().strip() for x in a.split(',')]
  171.         if not device.validateBusList(bus, False):
  172.             mod.usage(error_msg=['Invalid bus name'])
  173.  
  174.     elif o in ('-t', '--type'):
  175.         setup_fax, setup_print = False, False
  176.         a = a.strip().lower()
  177.         for aa in a.split(','):
  178.             if aa.strip() not in ('print', 'fax'):
  179.                 mod.usage(error_msg=['Invalid type.'])
  180.  
  181.             if aa.strip() == 'print':
  182.                 setup_print = True
  183.  
  184.             elif aa.strip() == 'fax':
  185.                 if not prop.fax_build:
  186.                     log.error("Cannot enable fax setup - HPLIP not built with fax enabled.")
  187.                 else:
  188.                     setup_fax = True
  189.  
  190.     elif o == '--port':
  191.         try:
  192.             jd_port = int(a)
  193.         except ValueError:
  194.             #log.error("Invalid port number. Must be between 1 and 3 inclusive.")
  195.             mod.usage(error_msg=['Invalid port number. Must be between 1 and 3 inclusive.'])
  196.  
  197.     elif o in ('-a', '--auto'):
  198.         auto = True
  199.  
  200.     elif o in ('-r', '--rm', '--remove'):
  201.         remove = True
  202.  
  203.  
  204. try:
  205.     param = mod.args[0]
  206. except IndexError:
  207.     param = ''
  208.  
  209. log.debug("param=%s" % param)
  210.  
  211.  
  212. if mode == GUI_MODE:
  213.     if ui_toolkit == 'qt3':
  214.         if not utils.canEnterGUIMode():
  215.             log.error("%s requires GUI support (try running with --qt4). Also, try using interactive (-i) mode." % __mod__)
  216.             sys.exit(1)
  217.     else:
  218.         if not utils.canEnterGUIMode4():
  219.             log.error("%s requires GUI support (try running with --qt3). Also, try using interactive (-i) mode." % __mod__)
  220.             sys.exit(1)
  221.  
  222. if mode == GUI_MODE:
  223.     if ui_toolkit == 'qt3':
  224.         try:
  225.             from qt import *
  226.             from ui import setupform
  227.         except ImportError:
  228.             log.error("Unable to load Qt3 support. Is it installed?")
  229.             sys.exit(1)
  230.  
  231.         if remove:
  232.             log.warn("-r/--rm/--remove not supported in qt3 mode.")
  233.  
  234.         app = QApplication(sys.argv)
  235.         QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
  236.  
  237.         if loc is None:
  238.             loc = user_conf.get('ui', 'loc', 'system')
  239.             if loc.lower() == 'system':
  240.                 loc = str(QTextCodec.locale())
  241.                 log.debug("Using system locale: %s" % loc)
  242.  
  243.         if loc.lower() != 'c':
  244.             e = 'utf8'
  245.             try:
  246.                 l, x = loc.split('.')
  247.                 loc = '.'.join([l, e])
  248.             except ValueError:
  249.                 l = loc
  250.                 loc = '.'.join([loc, e])
  251.  
  252.             log.debug("Trying to load .qm file for %s locale." % loc)
  253.             trans = QTranslator(None)
  254.  
  255.             qm_file = 'hplip_%s.qm' % l
  256.             log.debug("Name of .qm file: %s" % qm_file)
  257.             loaded = trans.load(qm_file, prop.localization_dir)
  258.  
  259.             if loaded:
  260.                 app.installTranslator(trans)
  261.             else:
  262.                 loc = 'c'
  263.  
  264.         if loc == 'c':
  265.             log.debug("Using default 'C' locale")
  266.         else:
  267.             log.debug("Using locale: %s" % loc)
  268.             QLocale.setDefault(QLocale(loc))
  269.             prop.locale = loc
  270.             try:
  271.                 locale.setlocale(locale.LC_ALL, locale.normalize(loc))
  272.             except locale.Error:
  273.                 pass
  274.  
  275.         try:
  276.             w = setupform.SetupForm(bus, param, jd_port)
  277.         except Error:
  278.             log.error("Unable to connect to HPLIP I/O. Please (re)start HPLIP and try again.")
  279.             sys.exit(1)
  280.  
  281.         app.setMainWidget(w)
  282.         w.show()
  283.  
  284.         app.exec_loop()
  285.  
  286.     else: # qt4
  287.         try:
  288.             from PyQt4.QtGui import QApplication, QMessageBox
  289.             from ui4.setupdialog import SetupDialog
  290.         except ImportError:
  291.             log.error("Unable to load Qt4 support. Is it installed?")
  292.             sys.exit(1)
  293.  
  294.         app = QApplication(sys.argv)
  295.  
  296.         dlg = SetupDialog(None, param, jd_port, device_uri, remove)
  297.         dlg.show()
  298.         try:
  299.             log.debug("Starting GUI loop...")
  300.             app.exec_()
  301.         except KeyboardInterrupt:
  302.             sys.exit(0)
  303.  
  304.  
  305. else: # INTERACTIVE_MODE
  306.     try:
  307.  
  308.         cups.setPasswordCallback(showPasswordUI)
  309.  
  310.         if remove:
  311.             log.error("-r/--rm/--remove not supported in -i mode.")
  312.             sys.exit(1)
  313.  
  314.         if not auto:
  315.             log.info("(Note: Defaults for each question are maked with a '*'. Press <enter> to accept the default.)")
  316.             log.info("")
  317.  
  318.         # ******************************* MAKEURI
  319.         if param:
  320.             device_uri, sane_uri, fax_uri = device.makeURI(param, jd_port)
  321.  
  322.         # ******************************* CONNECTION TYPE CHOOSER
  323.         if not device_uri and bus is None:
  324.             bus = tui.connection_table()
  325.  
  326.             if bus is None:
  327.                 sys.exit(0)
  328.  
  329.             log.info("\nUsing connection type: %s" % bus[0])
  330.  
  331.             log.info("")
  332.  
  333.         # ******************************* DEVICE CHOOSER
  334.  
  335.         if not device_uri:
  336.             device_uri = mod.getDeviceUri(device_uri, devices=device.probeDevices(bus))
  337.  
  338.         # ******************************* QUERY MODEL AND COLLECT PPDS
  339.         log.info(log.bold("\nSetting up device: %s\n" % device_uri))
  340.  
  341.         log.info("")
  342.         print_uri = device_uri.replace("hpfax:", "hp:")
  343.         fax_uri = device_uri.replace("hp:", "hpfax:")
  344.  
  345.         back_end, is_hp, bus, model, \
  346.             serial, dev_file, host, zc, port = \
  347.             device.parseDeviceURI(device_uri)
  348.  
  349.         log.debug("Model=%s" % model)
  350.         mq = device.queryModelByURI(device_uri)
  351.  
  352.         if not mq or mq.get('support-type', SUPPORT_TYPE_NONE) == SUPPORT_TYPE_NONE:
  353.             log.error("Unsupported printer model.")
  354.             sys.exit(1)
  355.  
  356.         if mq.get('fax-type', FAX_TYPE_NONE) in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED) and setup_fax:
  357.             #log.warning("Cannot setup fax - device does not have fax feature.")
  358.             setup_fax = False
  359.  
  360.         # ******************************* PLUGIN
  361.  
  362.         norm_model = models.normalizeModelName(model).lower()
  363.         plugin = mq.get('plugin', PLUGIN_NONE)
  364.  
  365.         plugin_installed = utils.to_bool(sys_state.get('plugin', 'installed', '0'))
  366.         if plugin > PLUGIN_NONE and not plugin_installed:
  367.             tui.header("PLUG-IN INSTALLATION")
  368.  
  369.             hp_plugin = utils.which('hp-plugin')
  370.  
  371.             if hp_plugin:
  372.                 if prop.gui_build:
  373.                     os.system("hp-plugin -i")
  374.                 else:
  375.                     os.system("hp-plugin")
  376.  
  377.         ppds = cups.getSystemPPDs()
  378.  
  379.         default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
  380.         stripped_model = cups.stripModel2(default_model)
  381.  
  382.         installed_print_devices = device.getSupportedCUPSDevices(['hp'])
  383.         for d in installed_print_devices.keys():
  384.             for p in installed_print_devices[d]:
  385.                 log.debug("found print queue '%s'" % p)
  386.  
  387.         installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
  388.         for d in installed_fax_devices.keys():
  389.             for f in installed_fax_devices[d]:
  390.                 log.debug("found fax queue '%s'" % f)
  391.  
  392.         # ******************************* PRINT QUEUE SETUP
  393.         if setup_print:
  394.  
  395.             tui.header("PRINT QUEUE SETUP")
  396.  
  397.             if not auto and print_uri in installed_print_devices:
  398.                 log.warning("One or more print queues already exist for this device: %s." %
  399.                     ', '.join(installed_print_devices[print_uri]))
  400.  
  401.                 ok, setup_print = tui.enter_yes_no("\nWould you like to install another print queue for this device", 'n')
  402.                 if not ok: sys.exit(0)
  403.  
  404.         if setup_print:
  405.             if auto:
  406.                 printer_name = default_model
  407.  
  408.             printer_default_model = default_model
  409.  
  410.             # Check for duplicate names
  411.             if device_uri in installed_print_devices and \
  412.                 printer_default_model in installed_print_devices[device_uri]:
  413.                     i = 2
  414.                     while True:
  415.                         t = printer_default_model + "_%d" % i
  416.                         if t not in installed_print_devices[device_uri]:
  417.                             printer_default_model += "_%d" % i
  418.                             break
  419.                         i += 1
  420.  
  421.             if not auto:
  422.                 if printer_name is None:
  423.                     while True:
  424.                         printer_name = raw_input(log.bold("\nPlease enter a name for this print queue (m=use model name:'%s'*, q=quit) ?" % printer_default_model))
  425.  
  426.                         if printer_name.lower().strip() == 'q':
  427.                             log.info("OK, done.")
  428.                             sys.exit(0)
  429.  
  430.                         if not printer_name or printer_name.lower().strip() == 'm':
  431.                             printer_name = printer_default_model
  432.  
  433.                         name_ok = True
  434.  
  435.                         for d in installed_print_devices.keys():
  436.                             for p in installed_print_devices[d]:
  437.                                 if printer_name == p:
  438.                                     log.error("A print queue with that name already exists. Please enter a different name.")
  439.                                     name_ok = False
  440.                                     break
  441.  
  442.                         for d in installed_fax_devices.keys():
  443.                             for f in installed_fax_devices[d]:
  444.                                 if printer_name == f:
  445.                                     log.error("A fax queue with that name already exists. Please enter a different name.")
  446.                                     name_ok = False
  447.                                     break
  448.  
  449.                         for c in printer_name:
  450.                             if c in cups.INVALID_PRINTER_NAME_CHARS:
  451.                                 log.error("Invalid character '%s' in printer name. Please enter a name that does not contain this character." % c)
  452.                                 name_ok = False
  453.  
  454.                         if name_ok:
  455.                             break
  456.             else:
  457.                 printer_name = printer_default_model
  458.  
  459.             log.info("Using queue name: %s" % printer_name)
  460.  
  461.             default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
  462.             stripped_model = default_model.lower().replace('hp-', '').replace('hp_', '')
  463.  
  464.             log.info("Locating PPD file... Please wait.")
  465.             print_ppd = cups.getPPDFile2(stripped_model, ppds)
  466.             enter_ppd = False
  467.  
  468.             if print_ppd is None:
  469.                 enter_ppd = True
  470.                 log.error("Unable to find an appropriate PPD file.")
  471.  
  472.             else:
  473.                 print_ppd, desc = print_ppd
  474.                 log.info("\nFound PPD file: %s" % print_ppd)
  475.  
  476.                 log.info("Description: %s" % desc)
  477. #
  478.                 if not auto:
  479.                     log.info("\nNote: The model number may vary slightly from the actual model number on the device.")
  480.                     ok, ans = tui.enter_yes_no("\nDoes this PPD file appear to be the correct one")
  481.                     if not ok: sys.exit(0)
  482.                     if not ans: enter_ppd = True
  483.  
  484.  
  485.             if enter_ppd:
  486.                 enter_ppd = False
  487.  
  488.                 ok, enter_ppd = tui.enter_yes_no("\nWould you like to specify the path to the correct PPD file to use", 'n')
  489.                 if not ok: sys.exit(0)
  490.  
  491.                 if enter_ppd:
  492.                     ok = False
  493.  
  494.                     while True:
  495.                         user_input = raw_input(log.bold("\nPlease enter the full filesystem path to the PPD file to use (q=quit) :"))
  496.  
  497.                         if user_input.lower().strip() == 'q':
  498.                             log.info("OK, done.")
  499.                             sys.exit(0)
  500.  
  501.                         file_path = user_input
  502.  
  503.                         if os.path.exists(file_path) and os.path.isfile(file_path):
  504.  
  505.                             if file_path.endswith('.gz'):
  506.                                 nickname = gzip.GzipFile(file_path, 'r').read(4096)
  507.                             else:
  508.                                 nickname = file(file_path, 'r').read(4096)
  509.  
  510.                             try:
  511.                                 desc = nickname_pat.search(nickname).group(1)
  512.                             except AttributeError:
  513.                                 desc = ''
  514.  
  515.                             if desc:
  516.                                 log.info("Description for the file: %s" % desc)
  517.                             else:
  518.                                 log.error("No PPD 'NickName' found. This file may not be a valid PPD file.")
  519.  
  520.                             ok, ans = tui.enter_yes_no("\nUse this file")
  521.                             if not ok: sys.exit(0)
  522.                             if ans: print_ppd = file_path
  523.  
  524.                         else:
  525.                             log.error("File not found or not an appropriate (PPD) file.")
  526.  
  527.                         if ok:
  528.                             break
  529.                 else:
  530.                     log.error("PPD file required. Setup cannot continue. Exiting.")
  531.                     sys.exit(1)
  532.  
  533.             if auto:
  534.                 location, info = '', 'Automatically setup by HPLIP'
  535.             else:
  536.                 while True:
  537.                     location = raw_input(log.bold("Enter a location description for this printer (q=quit) ?"))
  538.  
  539.                     if location.strip().lower() == 'q':
  540.                         log.info("OK, done.")
  541.                         sys.exit(0)
  542.  
  543.                     # TODO: Validate chars
  544.                     break
  545.  
  546.                 while True:
  547.                     info = raw_input(log.bold("Enter additonal information or notes for this printer (q=quit) ?"))
  548.  
  549.                     if info.strip().lower() == 'q':
  550.                         log.info("OK, done.")
  551.                         sys.exit(0)
  552.  
  553.                     # TODO: Validate chars
  554.                     break
  555.  
  556.             log.info(log.bold("\nAdding print queue to CUPS:"))
  557.             log.info("Device URI: %s" % print_uri)
  558.             log.info("Queue name: %s" % printer_name)
  559.             log.info("PPD file: %s" % print_ppd)
  560.             log.info("Location: %s" % location)
  561.             log.info("Information: %s" % info)
  562.  
  563.             log.debug("Restarting CUPS...")
  564.             status, output = utils.run(restart_cups())
  565.             log.debug("Restart CUPS returned: exit=%d output=%s" % (status, output))
  566.  
  567.             cups.setPasswordPrompt("You do not have permission to add a printer.")
  568.             if not os.path.exists(print_ppd): # assume foomatic: or some such
  569.                 status, status_str = cups.addPrinter(printer_name.encode('utf8'), print_uri,
  570.                     location, '', print_ppd, info)
  571.             else:
  572.                 status, status_str = cups.addPrinter(printer_name.encode('utf8'), print_uri,
  573.                     location, print_ppd, '', info)
  574.  
  575.             log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
  576.  
  577.             installed_print_devices = device.getSupportedCUPSDevices(['hp'])
  578.  
  579.             if print_uri not in installed_print_devices or \
  580.                 printer_name not in installed_print_devices[print_uri]:
  581.  
  582.                 log.error("Printer queue setup failed. Please restart CUPS and try again.")
  583.                 sys.exit(1)
  584.             else:
  585.                 pass
  586.                 # TODO:
  587.                 #service.sendEvent(hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=print_uri)
  588.  
  589.  
  590.         # ******************************* FAX QUEUE SETUP
  591.         if setup_fax and not prop.fax_build:
  592.             log.error("Cannot setup fax - HPLIP not built with fax enabled.")
  593.             setup_fax = False
  594.  
  595.         if setup_fax:
  596.  
  597.             try:
  598.                 from fax import fax
  599.             except ImportError:
  600.                 # This can fail on Python < 2.3 due to the datetime module
  601.                 setup_fax = False
  602.                 log.warning("Fax setup disabled - Python 2.3+ required.")
  603.  
  604.         log.info("")
  605.  
  606.         if setup_fax:
  607.  
  608.             tui.header("FAX QUEUE SETUP")
  609.  
  610.             if not auto and fax_uri in installed_fax_devices:
  611.                 log.warning("One or more fax queues already exist for this device: %s." % ', '.join(installed_fax_devices[fax_uri]))
  612.                 ok, setup_fax = tui.enter_yes_no("\nWould you like to install another fax queue for this device", 'n')
  613.                 if not ok: sys.exit(0)
  614.  
  615.         if setup_fax:
  616.             if auto: # or fax_name is None:
  617.                 fax_name = default_model + '_fax'
  618.  
  619.             fax_default_model = default_model + '_fax'
  620.  
  621.             # Check for duplicate names
  622.             if fax_uri in installed_fax_devices and \
  623.                 fax_default_model in installed_fax_devices[fax_uri]:
  624.                     i = 2
  625.                     while True:
  626.                         t = fax_default_model + "_%d" % i
  627.                         if t not in installed_fax_devices[fax_uri]:
  628.                             fax_default_model += "_%d" % i
  629.                             break
  630.                         i += 1
  631.  
  632.             if not auto:
  633.                 if fax_name is None:
  634.                     while True:
  635.                         fax_name = raw_input(log.bold("\nPlease enter a name for this fax queue (m=use model name:'%s'*, q=quit) ?" % fax_default_model))
  636.  
  637.                         if fax_name.lower().strip() == 'q':
  638.                             log.info("OK, done.")
  639.                             sys.exit(0)
  640.  
  641.                         if not fax_name or fax_name.lower().strip() == 'm':
  642.                             fax_name = fax_default_model
  643.  
  644.                         name_ok = True
  645.  
  646.                         for d in installed_print_devices.keys():
  647.                             for p in installed_print_devices[d]:
  648.                                 if fax_name == p:
  649.                                     log.error("A print queue with that name already exists. Please enter a different name.")
  650.                                     name_ok = False
  651.                                     break
  652.  
  653.                         for d in installed_fax_devices.keys():
  654.                             for f in installed_fax_devices[d]:
  655.                                 if fax_name == f:
  656.                                     log.error("A fax queue with that name already exists. Please enter a different name.")
  657.                                     name_ok = False
  658.                                     break
  659.  
  660.                         for c in fax_name:
  661.                             if c in (' ', '#', '/', '%'):
  662.                                 log.error("Invalid character '%s' in fax name. Please enter a name that does not contain this character." % c)
  663.                                 name_ok = False
  664.  
  665.                         if name_ok:
  666.                             break
  667.  
  668.             else:
  669.                 fax_name = fax_default_model
  670.  
  671.             log.info("Using queue name: %s" % fax_name)
  672.  
  673.             fax_type = mq.get('fax-type', FAX_TYPE_NONE)
  674.  
  675.             if prop.hpcups_build:
  676.                 if fax_type == FAX_TYPE_SOAP:
  677.                     fax_ppd_name = 'HP-Fax2-hpcups'
  678.                 else:
  679.                     fax_ppd_name = 'HP-Fax-hpcups'
  680.             else: # hpijs
  681.                 if fax_type == FAX_TYPE_SOAP:
  682.                     fax_ppd_name = 'HP-Fax2-hpijs'
  683.                 else:
  684.                     fax_ppd_name = 'HP-Fax-hpijs'
  685.  
  686.             for f in ppds:
  687.                 if f.find(fax_ppd_name) >= 0:
  688.                     fax_ppd = f
  689.                     log.debug("Found PDD file: %s" % fax_ppd)
  690.                     break
  691.             else:
  692.                 log.error("Unable to find HP fax PPD file! Please check you HPLIP installation and try again.")
  693.                 sys.exit(1)
  694.  
  695.             if auto:
  696.                 location, info = '', 'Automatically setup by HPLIP'
  697.             else:
  698.                 while True:
  699.                     location = raw_input(log.bold("Enter a location description for this printer (q=quit) ?"))
  700.  
  701.                     if location.strip().lower() == 'q':
  702.                         log.info("OK, done.")
  703.                         sys.exit(0)
  704.  
  705.                     # TODO: Validate chars
  706.                     break
  707.  
  708.                 while True:
  709.                     info = raw_input(log.bold("Enter additonal information or notes for this printer (q=quit) ?"))
  710.  
  711.                     if info.strip().lower() == 'q':
  712.                         log.info("OK, done.")
  713.                         sys.exit(0)
  714.  
  715.                     # TODO: Validate chars
  716.                     break
  717.  
  718.             log.info(log.bold("\nAdding fax queue to CUPS:"))
  719.             log.info("Device URI: %s" % fax_uri)
  720.             log.info("Queue name: %s" % fax_name)
  721.             log.info("PPD file: %s" % fax_ppd)
  722.             log.info("Location: %s" % location)
  723.             log.info("Information: %s" % info)
  724.  
  725.             cups.setPasswordPrompt("You do not have permission to add a fax device.")
  726.             if not os.path.exists(fax_ppd): # assume foomatic: or some such
  727.                 status, status_str = cups.addPrinter(fax_name.encode('utf8'), fax_uri,
  728.                     location, '', fax_ppd, info)
  729.             else:
  730.                 status, status_str = cups.addPrinter(fax_name.encode('utf8'), fax_uri,
  731.                     location, fax_ppd, '', info)
  732.  
  733.             log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
  734.  
  735.             installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
  736.  
  737.             log.debug(installed_fax_devices)
  738.  
  739.             if fax_uri not in installed_fax_devices or \
  740.                 fax_name not in installed_fax_devices[fax_uri]:
  741.  
  742.                 log.error("Fax queue setup failed. Please restart CUPS and try again.")
  743.                 sys.exit(1)
  744.             else:
  745.                 pass
  746.                 # TODO:
  747.                 #service.sendEvent(hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=fax_uri)
  748.  
  749.  
  750.         # ******************************* FAX HEADER SETUP
  751.             tui.header("FAX HEADER SETUP")
  752.  
  753.             if auto:
  754.                 setup_fax = False
  755.             else:
  756.                 while True:
  757.                     user_input = raw_input(log.bold("\nWould you like to perform fax header setup (y=yes*, n=no, q=quit) ?")).strip().lower()
  758.  
  759.                     if user_input == 'q':
  760.                         log.info("OK, done.")
  761.                         sys.exit(0)
  762.  
  763.                     if not user_input:
  764.                         user_input = 'y'
  765.  
  766.                     setup_fax = (user_input == 'y')
  767.  
  768.                     if user_input in ('y', 'n', 'q'):
  769.                         break
  770.  
  771.                     log.error("Please enter 'y' or 'n'")
  772.  
  773.             if setup_fax:
  774.                 d = fax.getFaxDevice(fax_uri, disable_dbus=True)
  775.  
  776.                 try:
  777.                     d.open()
  778.                 except Error:
  779.                     log.error("Unable to communicate with the device. Please check the device and try again.")
  780.                 else:
  781.                     try:
  782.                         tries = 0
  783.                         ok = True
  784.  
  785.                         while True:
  786.                             tries += 1
  787.  
  788.                             try:
  789.                                 current_phone_num = str(d.getPhoneNum())
  790.                                 current_station_name = str(d.getStationName())
  791.                             except Error:
  792.                                 log.error("Could not communicate with device. Device may be busy. Please wait for retry...")
  793.                                 time.sleep(5)
  794.                                 ok = False
  795.  
  796.                                 if tries > 12:
  797.                                     break
  798.  
  799.                             else:
  800.                                 ok = True
  801.                                 break
  802.  
  803.                         if ok:
  804.                             while True:
  805.                                 if current_phone_num:
  806.                                     phone_num = raw_input(log.bold("\nEnter the fax phone number for this device (c=use current:'%s'*, q=quit) ?" % current_phone_num))
  807.                                 else:
  808.                                     phone_num = raw_input(log.bold("\nEnter the fax phone number for this device (q=quit) ?"))
  809.                                 if phone_num.strip().lower() == 'q':
  810.                                     log.info("OK, done.")
  811.                                     sys.exit(0)
  812.  
  813.                                 if current_phone_num and (not phone_num or phone_num.strip().lower() == 'c'):
  814.                                     phone_num = current_phone_num
  815.  
  816.                                 if len(phone_num) > 50:
  817.                                     log.error("Phone number length is too long (>50 characters). Please enter a shorter number.")
  818.                                     continue
  819.  
  820.                                 ok = True
  821.                                 for x in phone_num:
  822.                                     if x not in '0123456789-(+) ':
  823.                                         log.error("Invalid characters in phone number. Please only use 0-9, -, (, +, and )")
  824.                                         ok = False
  825.                                         break
  826.  
  827.                                 if not ok:
  828.                                     continue
  829.  
  830.                                 break
  831.  
  832.                             while True:
  833.                                 if current_station_name:
  834.                                     station_name = raw_input(log.bold("\nEnter the name and/or company for this device (c=use current:'%s'*, q=quit) ?" % current_station_name))
  835.                                 else:
  836.                                     station_name = raw_input(log.bold("\nEnter the name and/or company for this device (q=quit) ?"))
  837.                                 if station_name.strip().lower() == 'q':
  838.                                     log.info("OK, done.")
  839.                                     sys.exit(0)
  840.  
  841.                                 if current_station_name and (not station_name or station_name.strip().lower() == 'c'):
  842.                                     station_name = current_station_name
  843.  
  844.  
  845.                                 if len(station_name) > 50:
  846.                                     log.error("Name/company length is too long (>50 characters). Please enter a shorter name/company.")
  847.                                     continue
  848.                                 break
  849.  
  850.                             try:
  851.                                 d.setStationName(station_name)
  852.                                 d.setPhoneNum(phone_num)
  853.                             except Error:
  854.                                 log.error("Could not communicate with device. Device may be busy.")
  855.                             else:
  856.                                 log.info("\nParameters sent to device.")
  857.  
  858.                     finally:
  859.                         d.close()
  860.  
  861.         # ******************************* TEST PAGE
  862.         if setup_print:
  863.             print_test_page = False
  864.  
  865.             tui.header("PRINTER TEST PAGE")
  866.  
  867.             if auto:
  868.                 if testpage_in_auto_mode:
  869.                     print_test_page = True
  870.             else:
  871.                 ok, print_test_page = tui.enter_yes_no("\nWould you like to print a test page")
  872.                 if not ok: sys.exit(0)
  873.  
  874.             if print_test_page:
  875.                 path = utils.which('hp-testpage')
  876.  
  877.                 if printer_name:
  878.                     param = "-p%s" % printer_name
  879.                 else:
  880.                     param = "-d%s" % print_uri
  881.  
  882.                 if len(path) > 0:
  883.                     cmd = 'hp-testpage %s' % param
  884.                 else:
  885.                     cmd = 'python ./testpage.py %s' % param
  886.  
  887.                 log.debug(cmd)
  888.  
  889.                 os.system(cmd)
  890.  
  891.     except KeyboardInterrupt:
  892.         log.error("User exit")
  893.  
  894. log.info("")
  895. log.info("Done.")
  896.  
  897.